package com.terrynoya.fight.test
{
	import com.terrynoya.common.control.MLabel;
	import com.terrynoya.common.control.button.MButton;
	import com.terrynoya.common.control.button.MLabelButton;
	import com.terrynoya.common.core.MApplication;
	import com.terrynoya.common.core.MUIComponent;
	import com.terrynoya.common.layout.MVBoxLayout;
	import com.terrynoya.common.util.HashMap;
	import com.terrynoya.coreLib.MHashMap;
	import com.terrynoya.coreLib.events.MLoaderEvent;
	import com.terrynoya.coreLib.loader.MSWFLoader;
	import com.terrynoya.coreLib.loader.MTextLoader;
	import com.terrynoya.fight.animations.AirParser;
	import com.terrynoya.fight.animations.AnimationManager;
	import com.terrynoya.fight.char.Character;
	import com.terrynoya.fight.char.CharacterRender;
	import com.terrynoya.fight.char.Entity;
	import com.terrynoya.fight.combat.FightEngine;
	import com.terrynoya.fight.combat.Player;
	import com.terrynoya.fight.combat.PlayerConstants;
	import com.terrynoya.fight.commands.CommandSystem;
	import com.terrynoya.fight.data.parser.sff.SFFReader;
	import com.terrynoya.fight.data.parser.sff.SffParser;
	import com.terrynoya.fight.data.parser.sff.SpriteItem;
	import com.terrynoya.fight.data.parser.sff.SpriteMaker;
	import com.terrynoya.fight.emuns.Facing;
	import com.terrynoya.fight.emuns.PlayerButton;
	import com.terrynoya.fight.stateMachine.StateNumber;
	import com.terrynoya.fight.timer.MTimerEvent;
	import com.terrynoya.fight.timer.TimerManager;
	import com.terrynoya.geom.MVector2D;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.ui.Keyboard;
	import flash.utils.ByteArray;
	
	public class StateTriggerTest extends Sprite
	{
		private var _app:MApplication;
		
		private var _timer:TimerManager;
		
		private var _fightEngine:FightEngine;
		
		public static const PLYER_1:String = "player1";
		public static const PLYER_2:String = "player2";
		
		private var _cnsTxt:String;
		
		private var _player1keyMap:MHashMap;
		private var _player2keyMap:MHashMap;
		
		private var _spriteMaker:SpriteMaker;
		
		private var _airParser:AirParser;
		
		private var _inputLbl:MLabel;
		
		private var _cmdData:String;
		
		private var _stageByts:ByteArray;
		
		private var _buttonConfig:Array;
		private var _buttons:HashMap;
		
		public function StateTriggerTest(spriteMaker:SpriteMaker,airData:String,cmdData:String,cnsTxt:String,stageByts:ByteArray)
		{
			super();
			
			this._buttonConfig = new Array();
			this._buttonConfig.push(new PanelButtonVO("鬼烧",1100));
			this._buttonConfig.push(new PanelButtonVO("葵花",1000));
			this._buttonConfig.push(new PanelButtonVO("大招",2000));
			
			this._buttons = new HashMap();
			
			this._cmdData = cmdData;
			this._cnsTxt = cnsTxt;
			this._airParser = new AirParser();
			this._airParser.parse(airData);
			 
			this._spriteMaker = spriteMaker;
			this._fightEngine = new FightEngine(this.getBgView(stageByts));
			this._fightEngine.stage.zOffset = 210;
			this._fightEngine.stage.render.x = 100;
			this._fightEngine.stage.render.y = 100;
			this._fightEngine.stage.tension = 50;
			this.addChild(this._fightEngine.stage.render);
			
//			this._timer = new TimerManager(60);
//			this._timer.addEventListener(MTimerEvent.TIME_SNAP_UPDATE,onTimeUpdate);
//			this._timer.start();
			
			this.addEventListener(Event.ENTER_FRAME,loop);
			this.addEventListener(Event.ADDED_TO_STAGE,onAdded);
			
			this._inputLbl = new MLabel();
			this.addChild(this._inputLbl);
		}
		
		private function getBgView(bytes:ByteArray):SpriteItem
		{
			var maker:SpriteMaker = SffParser.decode(bytes);
			var item:SpriteItem = maker.getSprite(0,0);
			return item;
		}
		
		
		private function onTimeUpdate(e:MTimerEvent):void
		{
			this._fightEngine.update(e.snap);
		}
		
		private function loop(e:Event):void
		{
			this._fightEngine.update(0);
		}
		
		private function onKeyDown(e:KeyboardEvent):void
		{
			if(e.keyCode == 19)
			{
				this._fightEngine.pause = !this._fightEngine.pause;
			}
			else if(e.keyCode == Keyboard.F12)
			{
				this._fightEngine.stepForward();
			}
			this.stage.addEventListener(KeyboardEvent.KEY_UP,onKeyUp);
			var keyCode:int = e.keyCode;
			this.updateKeyDownCommand(keyCode,PLYER_1);
			this.updateKeyDownCommand(keyCode,PLYER_2);
		}
		
		private function updateKeyDownCommand(keyCode:int,playerId:String):void
		{
			var map:MHashMap = playerId == PLYER_1 ? this._player1keyMap :this._player2keyMap; 
			if(!map.containsKey(keyCode))
			{
				return;
			}
			var char:Character = this._fightEngine.getCharacterById(playerId);
			var input:int = map.getValue(keyCode);
			char.recieveInput(input,true);
//			char.commandManger.command = map.getValue(keyCode);
		}
		
		private function onKeyUp(e:KeyboardEvent):void
		{
			this.stage.addEventListener(KeyboardEvent.KEY_UP,onKeyUp);
			this.upateKeyUpCommand(e.keyCode,PLYER_1);
			this.upateKeyUpCommand(e.keyCode,PLYER_2);
		}
		
		private function upateKeyUpCommand(keyCode:int,playerId:String):void
		{
			var map:MHashMap = playerId == PLYER_1 ? this._player1keyMap :this._player2keyMap; 
			if(!map.containsKey(keyCode))
			{
				return;
			}
			var char:Character = this._fightEngine.getCharacterById(playerId);
			var input:int = map.getValue(keyCode);
			char.recieveInput(input,false);
//			char.commandManger.command = "";
		}
		
		private function onAdded(e:Event):void
		{
			this._app = new MApplication(this.stage);
			this.addChild(this._app);
			this.initPanel();
			this.init();
		}
		
		private function init():void
		{
			this._player1keyMap = new MHashMap();
			this._player1keyMap.put(Keyboard.W,PlayerButton.Up);
			this._player1keyMap.put(Keyboard.D,PlayerButton.Right);
			this._player1keyMap.put(Keyboard.S,PlayerButton.Down);
			this._player1keyMap.put(Keyboard.A,PlayerButton.Left);
			this._player1keyMap.put(Keyboard.J,PlayerButton.X);
			this._player1keyMap.put(Keyboard.K,PlayerButton.A);
			this._player1keyMap.put(Keyboard.L,PlayerButton.Y);
			this._player1keyMap.put(Keyboard.U,PlayerButton.B);
			
			this._player2keyMap = new MHashMap();
			this._player2keyMap.put(Keyboard.UP,PlayerButton.Up);
			this._player2keyMap.put(Keyboard.LEFT,PlayerButton.Left);
			this._player2keyMap.put(Keyboard.DOWN,PlayerButton.Down);
			this._player2keyMap.put(Keyboard.RIGHT,PlayerButton.Right);
			this._player2keyMap.put(Keyboard.V,PlayerButton.X);
			this._player2keyMap.put(Keyboard.B,PlayerButton.A);
			this._player2keyMap.put(Keyboard.N,PlayerButton.Y);
			this._player2keyMap.put(Keyboard.M,PlayerButton.B);
			
			//			this._player2keyMap.put(Keyboard.NUMBER_1,"x");
			//			this._player2keyMap.put(Keyboard.NUMBER_2,"a");
			//			this._player2keyMap.put(Keyboard.NUMBER_3,"y");
			//			this._player2keyMap.put(Keyboard.NUMBER_4,"b");
			
			var chara1:Character = this.createChara(PLYER_1,Facing.RIGHT,new MVector2D(177.5,0));
			chara1.playerConst = this.initConst();
			chara1.stateManager.states = this._fightEngine.getStates(this._cnsTxt);
			chara1.stateManager.changeState(StateNumber.Standing);
			chara1.team = 1;
			
			var chara2:Character = this.createChara(PLYER_2,Facing.RIGHT,new MVector2D(317.5,0));
			chara2.playerConst = this.initConst();
			chara2.stateManager.states = this._fightEngine.getStates(this._cnsTxt);
			chara2.stateManager.changeState(StateNumber.Standing);
			chara2.team = 2;
			
			this._fightEngine.stage.characterLayer.addChild(chara2.view);
			this._fightEngine.stage.characterLayer.addChild(chara1.view);
			
			//			this._timer.start();
			this.stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyDown);
		}
		
		private function initPanel():void
		{
			var layout:MVBoxLayout = new MVBoxLayout();
			var panel:MUIComponent = new MUIComponent();
			panel.y = 300;
			this._app.addChild(panel);
			layout.source = panel;
			
			for (var i:int = 0; i < this._buttonConfig.length; i++) 
			{
				var vo:PanelButtonVO = this._buttonConfig[i];
				var btn:MLabelButton = new MLabelButton();
				btn.addEventListener(MouseEvent.CLICK,onBtnClick);
				btn.text = vo.name;
				this._buttons.put(btn,vo);
				panel.addChild(btn);
			}
			
			layout.update();
		}
		
		private function onBtnClick(e:MouseEvent):void
		{
			var btn:MButton = MButton(e.currentTarget);
			var vo:PanelButtonVO = this._buttons.getValue(btn);
			var player:Character = this._fightEngine.getCharacterById(PLYER_2);
			player.stateManager.changeState(vo.stateId);
		}
		
		private function onkfpBtnClick(e:MouseEvent):void
		{
			var player:Character = this._fightEngine.getCharacterById(PLYER_1);
			player.stateManager.changeState(1000);
		}
		
		private function onUpperClick(e:MouseEvent):void
		{
			var player:Character = this._fightEngine.getCharacterById(PLYER_1);
			player.stateManager.changeState(3050);
		}
		
		private function initConst():PlayerConstants
		{
			var pc:PlayerConstants = new PlayerConstants();
			pc.walkForward = 2.4;
			pc.walkBackward = -2.2;
			pc.liedowntime = 60;
			pc.attackDistance = 160;
			pc.jumpForward = new MVector2D(2.5,-8.4);
			pc.jumpNeutral = new MVector2D(0,-8.4);
			pc.jumpBack = new MVector2D(-2.55,-8.4);
			pc.standFriction = 0.85;
			pc.crunchFriction = 0.82;
			pc.vertAcceleration = 0.44;
			return pc;
		}
		
		private function createChara(id:String,facing:int,pos:MVector2D):Character
		{
			var render:CharacterRender = new CharacterRender(this._spriteMaker);
			var chara:Character = new Player(this._fightEngine);
			chara.render = render;
			chara.id = id;
			chara.setCommands(CommandSystem.build(this._cmdData));
			this._fightEngine.addEntity(chara);
//			this._fightEngine.stage.render.addChild(chara.view);
			
			var aniManger:AnimationManager = new AnimationManager(this._airParser.animations);
			chara.animationManager = aniManger;
			chara.facing = facing;
			chara.position = pos;
			
			chara.dimension.groundFrontWidth = 15;
			chara.dimension.groundBackWidth = 16;
			return chara;
		}
	}
}